package com.zcj.pdf;

import java.awt.Color;
import java.awt.Font;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.log4j.Logger;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.springframework.util.StringUtils;

/**
 * 饼图、柱状图生成工具
 * 
 * @author zhanglei: 2016年11月9日 下午4:22:31
 * 
 */
public class JFreeChartUtils {
	private static Logger log = Logger.getLogger(JFreeChartUtils.class);
	private final static Font CN_TITLE_FONT = new Font("宋体", Font.CENTER_BASELINE, 20);
	private final static Font CN_LABLE_FONT = new Font("宋体", Font.CENTER_BASELINE, 15);
	private final static Font CN_ITEM_FONT = new Font("宋体", Font.CENTER_BASELINE, 15);
	private final static Font ENG_FONT = new Font("宋体", Font.CENTER_BASELINE, 12);

	/**
	 * 利用JFreeChart生成饼图
	 * 
	 * @param title
	 * @param data
	 * @return
	 */
	public static JFreeChart createPieChart(String title, boolean isRemark, Map<String, Number> data) {
		boolean isALLNull = isAllNull1(data);
		DefaultPieDataset dataset = createPieDataset(data, isALLNull);
		JFreeChart chart = ChartFactory.createPieChart(title, // 饼图的标题
				dataset, // data
				isRemark, // 是否显示图例注释
				false, // 是否生成工具
				true);// 是否生成地址
		chart.getTitle().setFont(CN_TITLE_FONT);// 设置标题字体
		chart.setBackgroundPaint(Color.WHITE); // 设定背景色为白色
		if (isRemark)
			chart.getLegend().setItemFont(CN_TITLE_FONT);// 设置图例类别字体
		// 设置标题字体
		PiePlot pieplot = (PiePlot) chart.getPlot();
		// 设置饼图的颜色
		// color:['#f6da22','#bbe2e8','#6cacde']
		// for (Map.Entry<String, Number> entry : data.entrySet()) {
		// pieplot.setSectionPaint(entry.getKey(), new Color(160, 160, 255));
		// }

		// 设置前景的透明度
		pieplot.setForegroundAlpha(1.0f);
		// 设置无数据时的提示信息以及字体以及颜色
		pieplot.setNoDataMessage("无数据");
		pieplot.setNoDataMessageFont(CN_TITLE_FONT);
		pieplot.setNoDataMessagePaint(Color.RED);

		pieplot.setBackgroundPaint(Color.WHITE);
		// 去掉饼图的边框
		pieplot.setOutlinePaint(Color.WHITE); // 设置绘图面板外边的填充颜色
		pieplot.setShadowPaint(Color.WHITE); // 设置绘图面板阴影的填充颜色

		// 设置每一个扇形的标签颜色和字体
		if (isALLNull) {
			pieplot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}"));
		} else {
			DecimalFormat df = new DecimalFormat("0.00%");//获得一个DecimalFormat对象，主要是设置小数问题,表示小数点后保留两位。  
			NumberFormat nf = NumberFormat.getNumberInstance();//获得一个NumberFormat对象  
			StandardPieSectionLabelGenerator sp = new StandardPieSectionLabelGenerator(  
			        "{0}:{2}", nf, df);
			//获得StandardPieSectionLabelGenerator对象,生成的格式，{0}表示section名，{1}表示section的值，{2}表示百分比。可以自定义  
			pieplot.setLabelGenerator(sp);
		}
		pieplot.setLabelBackgroundPaint(null);// 标签背景颜色
		pieplot.setLabelOutlinePaint(null);// 标签边框颜色
		pieplot.setLabelShadowPaint(null);// 标签阴影颜色
		pieplot.setLabelFont(CN_LABLE_FONT);
		return chart;
	}

	/**
	 * 判断所有的选项是否为0或者null
	 * 
	 * @param data
	 * @return
	 */
	private static boolean isAllNull1(Map<String, Number> data) {
		boolean flag = true;
		for (Map.Entry<String, Number> entry : data.entrySet()) {
			System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
			if (!StringUtils.isEmpty(entry.getValue()) && entry.getValue().doubleValue() > 0.0d) {
				flag = false;
			}
		}
		return flag;
	}

	/***
	 * 饼图数据填充
	 * 
	 * @param isALLNull
	 * 
	 * @return
	 */
	public static DefaultPieDataset createPieDataset(Map<String, Number> data, boolean isALLNull) {
		DefaultPieDataset dataset = new DefaultPieDataset();
		// 如果数据全为0
		if (isALLNull)
			for (Map.Entry<String, Number> entry : data.entrySet()) {
				dataset.setValue(entry.getKey(), 1);
			}
		else
			for (Map.Entry<String, Number> entry : data.entrySet()) {
				System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
				dataset.setValue(entry.getKey(), entry.getValue());
			}
		// dataset.sortByValues(SortOrder.DESCENDING);//通过片区的值进行降序排序
		return dataset;
	}

	/**
	 * 利用JFreeChart生成折线图
	 * 
	 * @param title
	 * @param data
	 * @return
	 */
	public static JFreeChart createLineChart(String title, String xTitle, String yTitle, boolean isRemark,
			Map<String, Map<String, Number>> data) {
		boolean isAllNull = isAllNull2(data);
		CategoryDataset dataset = createDataset(data);
		JFreeChart chart = ChartFactory.createLineChart(title, // 折线图的地址
				xTitle, // x轴名称
				yTitle, // y轴名称
				dataset, // 具体数据
				PlotOrientation.VERTICAL, isRemark, // 是否显示图例
				false, // 是否生成工具
				true);// 是否生成地址
		chart.getTitle().setFont(CN_TITLE_FONT);// 设置标题字体
		chart.setBackgroundPaint(Color.WHITE); // 设定背景色为白色
		if (isRemark) {
			chart.getLegend().setItemFont(CN_TITLE_FONT);// 设置图例类别字体
		}
		// 设置标题字体
		CategoryPlot lineplot = (CategoryPlot) chart.getPlot();
		// 设置前景的透明度
		lineplot.setForegroundAlpha(1.0f);
		// 设置无数据时的提示信息以及字体以及颜色
		lineplot.setNoDataMessage("无数据");
		lineplot.setNoDataMessageFont(CN_TITLE_FONT);
		lineplot.setNoDataMessagePaint(Color.RED);

		// 设置横坐标的字体颜色
		CategoryAxis domainAxis = lineplot.getDomainAxis();
		domainAxis.setLabelFont(CN_LABLE_FONT);
		domainAxis.setTickLabelFont(ENG_FONT);// 轴数值
		domainAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);// 横轴上的
		// 设置距离图片左端距离
		domainAxis.setLowerMargin(0.05);
		// 设置距离图片右端距离
		domainAxis.setUpperMargin(0.05);
		// 横轴 lable 的位置 横轴上的 Lable 45度倾斜 DOWN_45
		domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

		// 设置纵坐标的字体和颜色
		ValueAxis valueAxis = lineplot.getRangeAxis();
		valueAxis.setLabelFont(CN_LABLE_FONT);
		valueAxis.setTickLabelFont(ENG_FONT);// 轴数值
		// 设置最高的一个 Item 与图片顶端的距离
		valueAxis.setUpperMargin(0.15);
		// 设置最低的一个 Item 与图片底端的距离
		valueAxis.setLowerMargin(0.15);

		// Y轴取值范围（下面不能出现 valueAxis.setAutoRange(true) 否则不起作用）
		// 最小值显示0
		valueAxis.setLowerBound(0);
		// 如果数据全为空，则设置一下Y轴最大值
		if (isAllNull)
			valueAxis.setUpperBound(100);
		// 不自动分配Y轴数据
		valueAxis.setAutoRange(false);

		LineAndShapeRenderer lineandshaperenderer = (LineAndShapeRenderer) lineplot.getRenderer();
		lineandshaperenderer.setBaseShapesVisible(true); // series 点（即数据点）可见
		// lineandshaperenderer.setBaseLinesVisible(true); // series
		// 点（即数据点）间有连线可见
		// 显示折点数据
		lineandshaperenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		lineandshaperenderer.setBaseItemLabelsVisible(true);

		lineplot.setRangeGridlinePaint(Color.LIGHT_GRAY);// 背景底部横虚线
		lineplot.setOutlinePaint(Color.WHITE);// 边界线

		lineplot.setBackgroundPaint(Color.WHITE);
		// 去掉边框
		lineplot.setOutlinePaint(Color.WHITE); // 设置绘图面板外边的填充颜色
		return chart;
	}

	/**
	 * 利用JFreeChart生成柱状图
	 * 
	 * @param title
	 * @param data
	 * @return
	 */
	public static JFreeChart createBarChart(String title, String xTitle, String yTitle, boolean isRemark,
			Map<String, Map<String, Number>> data) {
		boolean isAllNull = isAllNull2(data);
		CategoryDataset dataset = createDataset(data);
		JFreeChart chart = ChartFactory.createBarChart(title, // 折线图的地址
				xTitle, // x轴名称
				yTitle, // y轴名称
				dataset, // 具体数据
				PlotOrientation.VERTICAL, isRemark, // 是否显示图例
				false, // 是否生成工具
				true);// 是否生成地址
		chart.getTitle().setFont(CN_TITLE_FONT);// 设置标题字体
		chart.setBackgroundPaint(Color.WHITE); // 设定背景色为白色
		if (isRemark)
			chart.getLegend().setItemFont(CN_ITEM_FONT);// 设置图例类别字体
		// 设置标题字体
		CategoryPlot barplot = (CategoryPlot) chart.getPlot();
		// 设置前景的透明度
		barplot.setForegroundAlpha(1.0f);
		// 设置无数据时的提示信息以及字体以及颜色
		barplot.setNoDataMessage("无数据");
		barplot.setNoDataMessageFont(CN_TITLE_FONT);
		barplot.setNoDataMessagePaint(Color.RED);

		// 设置横坐标的字体颜色
		CategoryAxis domainAxis = barplot.getDomainAxis();
		domainAxis.setLabelFont(CN_LABLE_FONT);
		domainAxis.setTickLabelFont(ENG_FONT);// 轴数值
		// 设置距离图片左端距离
		domainAxis.setLowerMargin(0.05);
		// 设置距离图片右端距离
		domainAxis.setUpperMargin(0.05);
		// 横轴 lable 的位置 横轴上的 Lable 45度倾斜 DOWN_45
		domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
		// // 横轴上的

		// 设置纵坐标的字体和颜色
		ValueAxis valueAxis = barplot.getRangeAxis();
		valueAxis.setLabelFont(CN_LABLE_FONT);
		valueAxis.setTickLabelFont(ENG_FONT);// 轴数值
		// 设置最高的一个 Item 与图片顶端的距离
		valueAxis.setUpperMargin(0.15);
		// 设置最低的一个 Item 与图片底端的距离
		valueAxis.setLowerMargin(0.15);
		// Y轴取值范围（下面不能出现 valueAxis.setAutoRange(true) 否则不起作用）
		// 最小值显示0
		valueAxis.setLowerBound(0);
		// 如果数据全为空，则设置一下Y轴最大值
		if (isAllNull)
			valueAxis.setUpperBound(100);
		// 不自动分配Y轴数据
		valueAxis.setAutoRange(false);

		// =====设置柱子的属性=====//
		BarRenderer renderer = (BarRenderer) barplot.getRenderer();
		// 设置柱子宽度
		renderer.setMaximumBarWidth(0.08);
		// 设置柱子高度
		renderer.setMinimumBarLength(0.1);
		// 设置柱子边框颜色
		renderer.setBaseOutlinePaint(Color.WHITE);
		// 设置柱子边框可见
		renderer.setDrawBarOutline(true);
		// 设置柱的颜色
		renderer.setSeriesPaint(0, Color.RED);
		// 设置每个地区所包含的平行柱的之间距离
		renderer.setItemMargin(0.5);
		chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
		// 显示每个柱的数值，并修改该数值的字体属性
		renderer.setIncludeBaseInRange(true);
		renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		renderer.setBaseItemLabelsVisible(true);

		barplot.setRangeGridlinePaint(Color.LIGHT_GRAY);// 背景底部横虚线
		barplot.setOutlinePaint(Color.WHITE);// 边界线

		barplot.setBackgroundPaint(Color.WHITE);
		// 去掉边框
		barplot.setOutlinePaint(Color.WHITE); // 设置绘图面板外边的填充颜色
		return chart;
	}

	/**
	 * 折线图的数据写入
	 * 
	 * @param data
	 * @return
	 */
	public static CategoryDataset createDataset(Map<String, Map<String, Number>> data) {
		DefaultCategoryDataset mDataset = new DefaultCategoryDataset();
		for (Map.Entry<String, Map<String, Number>> entry : data.entrySet()) {
			Map<String, Number> value = entry.getValue();
			Set<String> keys = value.keySet();
			// 如果是日期，则需要排序
			if (entry.getKey().equals("date")) {
				Comparator<String> comparator = new Comparator<String>() {
					public int compare(String s1, String s2) {
						return s1.compareTo(s2);
					}
				};
				Map<String, Number> sortMap = new TreeMap<String, Number>(comparator);
				sortMap.putAll(value);
				keys = sortMap.keySet();
			}
			for (String key : keys) {
				mDataset.addValue(value.get(key), entry.getKey(), key);
			}

		}
		return mDataset;
	}

	/**
	 * 判断数据是否全为空
	 * 
	 * @param data
	 * @return
	 */
	private static boolean isAllNull2(Map<String, Map<String, Number>> data) {
		boolean flag = true;
		for (Map.Entry<String, Map<String, Number>> entry : data.entrySet()) {
			Map<String, Number> value = entry.getValue();
			for (Map.Entry<String, Number> one : value.entrySet()) {
				System.out.println("key= " + one.getKey() + " and value= " + one.getValue());
				if (!StringUtils.isEmpty( one.getValue()) && one.getValue().doubleValue() > 0.0d) {
					flag = false;
				}
			}
		}
		return flag;
	}

	/**
	 * 折线图的数据写入
	 * 
	 * @param data
	 * @return
	 */
	public static boolean createImg(JFreeChart chart, String filePath, Integer length, Integer width) {
		try {
			if (length == null || width == null || length == 0 || width == 0) {
				length = 700;
				width = 400;
			}
			// 输出文件
			File outFile = new File(filePath);
			// 如果输出目标文件夹不存在，则创建
			if (!outFile.getParentFile().exists()) {
				outFile.getParentFile().mkdirs();
			}
			ChartUtilities.saveChartAsJPEG(outFile, chart, length, width);
		} catch (IOException e) {
			log.info("create pie/line/bar img failed........", e);
			return false;
		}
		return true;
	}

	

	
	public static void main1(String[] args) {
		// ================测试生成饼图=================//
		// Map<String, Number> data = new HashMap<String, Number>();
		// data.put("疲劳驾驶", 12);
		// data.put("注意力分散", 33);
		// data.put("车道偏离", 12);
		// data.put("遮挡，违规行为", null);
		// data.put("抽烟", 45);
		// data.put("打手机", 22);
		// JFreeChart chart = createPieChart("告警统计图",true, data);

		// =================测试生成折线图==================//
		Map<String, Map<String, Number>> data = new HashMap<String, Map<String, Number>>();
		Map<String, Number> value = new HashMap<String, Number>();
		value.put("4-12", 10);
		value.put("4-13", 34);
		value.put("4-14", 5);
		value.put("4-15", 41);
		value.put("4-16", 22);
		value.put("4-17", 10);
		data.put("疲劳驾驶", value);
		value = new HashMap<String, Number>();
		value.put("4-12", 20);
		value.put("4-13", 14);
		value.put("4-14", 44);
		value.put("4-15", 4);
		value.put("4-16", 27);
		value.put("4-17", 10);
		data.put("注意力分散", value);
		value = new HashMap<String, Number>();
		value.put("4-12", 7);
		value.put("4-13", 14);
		value.put("4-14", 15);
		value.put("4-15", 50);
		value.put("4-16", 31);
		value.put("4-17", 10);
		data.put("车道偏离", value);
		value = new HashMap<String, Number>();
		value.put("4-12", 6);
		value.put("4-13", 20);
		value.put("4-14", 16);
		value.put("4-15", 46);
		value.put("4-16", 25);
		value.put("4-17", 10);
		data.put("遮挡", value);
		JFreeChart chart = createLineChart("告警统计图", "日期", "告警数", true, data);


		// =================测试生成柱状图==============//
		// JFreeChart chart = createBarChart("告警统计图", "日期", "告警数",true, data);

		try {
			ChartUtilities.saveChartAsJPEG(new File("D:/wordtest/pie.jpg"), chart, 700, 400);
		} catch (IOException e) {
			System.out.println("生成图片错误");
			e.printStackTrace();
		}
	}
	
	
	public static void main(String[] args) {
		System.out.println("001020061176980".hashCode()%1000);
		
		
		DecimalFormat df = new DecimalFormat("0.00%");
		System.out.println(df.format(0.0d));
		System.out.println(df.format(0.67954d));
		System.out.println(df.format(0.111121d));
		System.out.println(df.format(0.115177d));
	}
	

}
